/**
 * @file TaskQue.cc
 * @author zziywang (zziywang@163.com)
 * @brief { life is too short to learn cpp! }
 * @version 1.0
 * @date 2022-05-08
 *
 * @copyright Copyright (c) 2022
 *
 */

#include "TaskQue.hh"

namespace snow
{
TaskQue::TaskQue(size_t size)
    : queSize_(size),
      mutex_(),
      notFull_(mutex_),
      notEmpty_(mutex_),
      isExit_(false) {}

// Producer
void TaskQue::push(ElemType elem)
{
    MutexLockGuard autolock(mutex_);
    while (full()) {
        notFull_.wait();
    }
    que_.push(elem);
    notEmpty_.notify();
}
// Consumer
ElemType TaskQue::pop()
{
    MutexLockGuard autolock(mutex_);
    while (!isExit_ && empty()) {
        notEmpty_.wait(); // 队列空但不退出时才会阻塞
    }
    if (!isExit_) {
        ElemType elem = que_.front();
        que_.pop();
        notFull_.notify();
        return elem;
    }
    return nullptr;
}

bool TaskQue::full() const
{
    return queSize_ == que_.size();
}
bool TaskQue::empty() const
{
    return que_.empty();
}

void TaskQue::notifyExit()
{
    isExit_ = true;
    notEmpty_.notifyAll();
}

} // namespace snow